package com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.publicOperate.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzfxqh.base.dict.service.DictItemService;
import com.css.fxfzfxqh.base.dict.viewobjects.DictEntityVo;
import com.css.fxfzfxqh.common.rest.JcsjRestManager;
import com.css.fxfzfxqh.common.rest.model.bo.JcLDBo;
import com.css.fxfzfxqh.common.rest.model.bo.JcPgaBo;
import com.css.fxfzfxqh.constants.FxfzConstants;
import com.css.fxfzfxqh.modules.buildingIndividual.entity.BuildingIndividualEntity;
import com.css.fxfzfxqh.modules.buildingIndividual.repository.BuildingIndividualRepository;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.BizException;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.StrategyFactoryException;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.param.QueryByVersionParam;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.service.FxqhBuildingGridDataVersionService;
import com.css.fxfzfxqh.modules.buildings.VO.CurveVo;
import com.css.fxfzfxqh.modules.buildings.calculationTasks.entity.CalculationTasks;
import com.css.fxfzfxqh.modules.buildings.calculationTasks.entity.YSXMainTable;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.casualtiesDE.entity.PCC;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.casualtiesDE.vo.Grid13VO;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.resistEarthquakesDE.vo.JcLd;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.resistEarthquakesDE.vo.JcPga;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.publicOperate.entity.PsHazardDataValue;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.publicOperate.repository.PublicOperateRepository;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.publicOperate.vo.BasicLibraryVo;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.util.YSXEntity;
import com.css.fxfzfxqh.modules.util.repository.PccRepository;
import com.css.fxfzfxqh.modules.util.repository.YSXRepository;
import com.css.fxfzfxqh.modules.vulnerabilityData.entity.BuildingIndividualVulnerability;
import com.css.fxfzfxqh.util.PlatformObjectUtils;
import com.css.fxfzfxqh.zcpt.sys.service.SysAreaService;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.math3.distribution.NormalDistribution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Dbj
 * @date 2023年09月07日  14:42
 * 概率评估计算中间公共操作、公共结果操作service
 */
@Service
public class PublicOperateService {
    @Resource
    private PublicOperateRepository publicOperateRepository;
    @Resource
    private SysAreaService sysAreaService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    JcsjRestManager jcsjRestManager;
    @Autowired
    DictItemService dictItemService;
    @Resource
    private FxqhBuildingGridDataVersionService fxqhBuildingGridDataVersionService;
    @Resource
    BuildingIndividualRepository buildingIndividualRepository;
    public static Map<String,List<BasicLibraryVo>> disrictMap = new HashMap<>();
    @Resource
    private YSXRepository ysxRepository;
    public static Map<String,List<YSXEntity>> disrictYsxMap = new HashMap<>();

    @Resource
    PccRepository pccRepository;

    public String getDistrictGeom(Map<String,Object> taskObj) throws Exception {
        String taskId = (String) taskObj.get("id");
        List<PCC> pccs = pccRepository.queryToponym(taskId);
        String radio2 = (String) taskObj.get("radio2");
        String geom = "";
        if("0".equals(radio2)){
            geom = this.getUnionGeomByCode(pccs);
        }else{
            geom = (String) taskObj.get("coordinate_range");
        }
        return geom;
    }
    /**
     * 根据省市区查询合并的空间数据
     */
    public String getUnionGeomByCode(List<PCC> pccList) throws Exception {
        Map<String, String> areaIdCodeMap = (Map<String, String>) JSON.parse((String) redisTemplate.opsForValue().get(FxfzConstants.CACHE_SYS_KEY + "areaIdCodeMap"));
        List<String> codeList = new ArrayList<>(pccList.size());
        pccList.forEach(pcc -> {
            String divisionIds = null;
            try {
                divisionIds = sysAreaService.getIdByCondition(URLEncoder.encode(pcc.getPpName(), "UTF-8"),
                        URLEncoder.encode(pcc.getCityName(), "UTF-8"), URLEncoder.encode(pcc.getName(), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            if (divisionIds != null) {
                String code = null;
                if (areaIdCodeMap==null||areaIdCodeMap.size()<1) {
                    code = sysAreaService.getDivisionCodeById(divisionIds.split("_")[2]);
                }else {
                    code = areaIdCodeMap.get(divisionIds.split("_")[2]);
                }
                codeList.add(code);
            }
        });
        if (codeList.size() == 0) {
            throw new RuntimeException("根据省市区县获取空间数据失败");
        }
        return jcsjRestManager.getUnionGeomByCodeList(codeList);
    }
    public String getGeomByCode(String province,String city,String county) throws Exception {
        Map<String, String> areaIdCodeMap = (Map<String, String>) JSON.parse((String) redisTemplate.opsForValue().get(FxfzConstants.CACHE_SYS_KEY + "areaIdCodeMap"));
        String divisionIds = null;
        try {
            divisionIds = sysAreaService.getIdByCondition(URLEncoder.encode(province, "UTF-8"),
                    URLEncoder.encode(city, "UTF-8"), URLEncoder.encode(county, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String code = "";
        if (divisionIds != null) {
            if (areaIdCodeMap==null||areaIdCodeMap.size()<1) {
                code = sysAreaService.getDivisionCodeById(divisionIds.split("_")[2]);
            }else {
                code = areaIdCodeMap.get(divisionIds.split("_")[2]);
            }
        }

        if (StringUtils.isBlank(code)) {
            throw new RuntimeException("根据省市区县获取空间数据失败");
        }
        return jcsjRestManager.getGeomByCode(code,"3");
    }

    /**
     * 根据空间数据和（烈度或pga查询对应的发生概率地震危险性数据）pirctureType:0：pga,1：烈度
     * 返回值例如：
     * kilometerGridId                    imValue   fImValue
     * 0343be2cdb1a42b0a6cb6589a21d1745	0.2	     1
     * 0343be2cdb1a42b0a6cb6589a21d1745	0.4	     1
     * 0343be2cdb1a42b0a6cb6589a21d1745	0.8	     1
     */
    public List<PsHazardDataValue> getPsHazardDataValueList(String pirctureType, String geom) {
        return publicOperateRepository.getPsHazardDataValueList(pirctureType, geom);
    }
    public List<PsHazardDataValue> getPsHazardDataValueList1(String pirctureType, String geom, CalculationTasks tasks) {
        return publicOperateRepository.getPsHazardDataValueList1(pirctureType, geom,tasks);
    }

    //根据经纬度查询对应发生概率
    public List<PsHazardDataValue> getFSGLbyLonAndLat(Double lon, Double lat,String pirctureType) {
        return publicOperateRepository.getFSGLbyLonAndLat(lon, lat,pirctureType);
    }

    //根据经纬度查询对应发生概率
    public List<PsHazardDataValue> getFSGLbyLonAndLat1(Double lon, Double lat,String pirctureType,CalculationTasks tasks) {
        return publicOperateRepository.getFSGLbyLonAndLat1(lon, lat,pirctureType,tasks);
    }

    /**
     * 组建数据   格式为<格网id,0.01,0.999969>
     */
    public Table<String, List<String>, List<BigDecimal>> buildPsHazardDataValue(List<PsHazardDataValue> list) {
        Map<String, List<PsHazardDataValue>> collect = list.stream().collect(Collectors.groupingBy(PsHazardDataValue::getId));
        Table<String, List<String>, List<BigDecimal>> table = HashBasedTable.create();
        collect.forEach((k, v) -> {
            List<String> valus = new ArrayList<>();
            List<BigDecimal> fvalus = new ArrayList<>();
            v.forEach(entity -> {
                valus.add(entity.getImValue());
                fvalus.add(entity.getFImValue());
            });
            table.put(k, valus, fvalus);
        });
        if (table.size() > 0) {
            return table;
        }
        return null;
    }
//    public Table<String, List<String>, List<BigDecimal>> buildPsHazardDataValue(List<PsHazardDataValue> list) {
//        Map<String, List<PsHazardDataValue>> collect = list.stream().collect(Collectors.groupingBy(PsHazardDataValue::getKilometerGridId));
//        Table<String, List<String>, List<BigDecimal>> table = HashBasedTable.create();
//        collect.forEach((k, v) -> {
//            List<String> valus = new ArrayList<>();
//            List<BigDecimal> fvalus = new ArrayList<>();
//            v.forEach(entity -> {
//                valus.add(entity.getImValue());
//                fvalus.add(entity.getFImValue());
//            });
//            table.put(k, valus, fvalus);
//        });
//        if (table.size() > 0) {
//            return table;
//        }
//        return null;
//    }

    public Table<String, List<String>, List<BigDecimal>> buildPsHazardDataValue2(List<PsHazardDataValue> list,String type) {
        Map<String, List<PsHazardDataValue>> collect = new HashMap<>();
        //type 1:网格;0:单体;
        if("1".equals(type)){
            collect = list.stream().collect(Collectors.groupingBy(PsHazardDataValue::getId));
        }else{
            collect = list.stream().collect(Collectors.groupingBy(PsHazardDataValue::getGeom));
        }

        Table<String, List<String>, List<BigDecimal>> table = HashBasedTable.create();
        collect.forEach((k, v) -> {
            List<String> valus = new ArrayList<>();
            List<BigDecimal> fvalus = new ArrayList<>();
            v.forEach(entity -> {
                valus.add(entity.getImValue());
                fvalus.add(entity.getFImValue());
            });
            table.put(k, valus, fvalus);
        });
        if (table.size() > 0) {
            return table;
        }
        return null;
    }
    /**
     * 组建数据   格式为<空间数据,0.01,0.999969>
     */
    public Table<String, List<String>, List<BigDecimal>> buildPsHazardDataValue1(List<PsHazardDataValue> list) {
        Map<String, List<PsHazardDataValue>> collect = list.stream().collect(Collectors.groupingBy(PsHazardDataValue::getGeom));
        Table<String, List<String>, List<BigDecimal>> table = HashBasedTable.create();
        collect.forEach((k, v) -> {
            List<String> valus = new ArrayList<>();
            List<BigDecimal> fvalus = new ArrayList<>();
            v.forEach(entity -> {
                valus.add(entity.getImValue());
                fvalus.add(entity.getFImValue());
            });
            table.put(k, valus, fvalus);
        });
        if (table.size() > 0) {
            return table;
        }
        return null;
    }

    /**
     * 根据空间数据和版本查询13表数据
     */
    public List<Grid13VO> getGrid13VOs(String geom, String version) throws StrategyFactoryException {
        //查询版本信息获取dataType
        List<DictEntityVo> dictItemByDictId = dictItemService.getDictItemByDictCode("jzwglgwlx");
        List<Grid13VO> list = new ArrayList<>();
        if (dictItemByDictId.size() > 0) {
            QueryByVersionParam queryByVersionParam = new QueryByVersionParam();
            queryByVersionParam.setVersionCode(version);
            queryByVersionParam.setGeom(geom);
            for (DictEntityVo vo : dictItemByDictId) {
                queryByVersionParam.setTypeCode(vo.getDictItemCode());
                List<Grid13VO> jggwList = fxqhBuildingGridDataVersionService.queryYwData(queryByVersionParam);
                list.addAll(jggwList);
            }
        }
        return list;
    }

    public BigDecimal getFuntionValue(JSONObject jsonObject, String im){
        BigDecimal subtract1 = new BigDecimal(im).subtract(BigDecimal.valueOf(Math.log(jsonObject.getBigDecimal("mr").doubleValue())));
        BigDecimal temp1 = subtract1.divide(jsonObject.getBigDecimal("br"), 4,
                BigDecimal.ROUND_HALF_UP);
        return selfCaculate(temp1);
    }


    public BigDecimal getFuntionValue( String mr,String br,String im){
        BigDecimal temp1 = BigDecimal.ZERO;
        try{
            BigDecimal subtract1 = new BigDecimal(im).subtract(BigDecimal.valueOf(Math.log(Double.parseDouble(mr))));
            temp1 = subtract1.divide(new BigDecimal(br), 4,BigDecimal.ROUND_HALF_UP);

        }catch (NumberFormatException e){
            e.printStackTrace();
        }
        return selfCaculate(temp1);
    }

    public List<BasicLibraryVo> getPgaOfYsx(String province,String city,String county) throws BizException {
        JSONArray pgaOfYsx = jcsjRestManager.getPgaOfYsx(province, city, county);
        List<BasicLibraryVo> list = JSONObject.parseArray(JSONObject.toJSONString(pgaOfYsx),BasicLibraryVo.class);
        list = list.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(
                                Comparator.comparing(o -> o.getStructureType() + "-" + o.getStructureType1() + "-" + o.getDefenseSituation()))), ArrayList::new));
        return list;
    }

    public  Map<String, BasicLibraryVo> getBasicMap(String province,String city,String county,Map<String,Map<String, BasicLibraryVo>> disrictMap) throws BizException {
        //list是根据省市县查询出来的易损性曲线数据
        if(!disrictMap.containsKey(province+"-"+city+"-"+county)){
            JSONArray pgaOfYsx = jcsjRestManager.getPgaOfYsx(province, city, county);
            List<BasicLibraryVo> list = JSONObject.parseArray(JSONObject.toJSONString(pgaOfYsx),BasicLibraryVo.class);
            //todo 要最终去掉该代码   去重
            list = list.stream()
                    .collect(Collectors.collectingAndThen(
                            Collectors.toCollection(() -> new TreeSet<>(
                                    Comparator.comparing(o -> o.getStructureType() + "-" + o.getStructureType1() + "-" + o.getDefenseSituation()))), ArrayList::new));
            Map<String, BasicLibraryVo> basicMap = list.stream().collect(Collectors.toMap(k -> k.getStructureType() + "-" + (PlatformObjectUtils.isNotEmpty(k.getStructureType1()) ? (k.getStructureType1() + "-" + k.getDefenseSituation()) : k.getDefenseSituation()), part -> part));
            disrictMap.put(province+"-"+city+"-"+county,basicMap);
            return basicMap;
        }
        return disrictMap.get(province + "-" + city + "-" + county);
    }
//    public Map<String, List<BigDecimal>> getYsxMap(String province, String city, String county) throws BizException {
//        Map<String, List<BigDecimal>> map = new HashMap<>();
//        //查询县的易损性数据
//        List<YSX> ysxList = null;
//        if(!disrictYsxMap.containsKey(province+"-"+city+"-"+county)){
//            ysxList =  ysxRepository.getYSX(province, city, county);
//            disrictYsxMap.put(province+"-"+city+"-"+county,ysxList);
//        }else{
//            ysxList = disrictYsxMap.get(province+"-"+city+"-"+county);
//        }
//        if (ysxList == null || ysxList.size() == 0) {
//            throw new RuntimeException("评估失败,请维护" + province + "-" + city + "-" + county + "的易损性数据");
//        }
//        // BiMap sfIntensityMap = BiMap
//        if (PlatformObjectUtils.isNotEmpty(ysxList)) {
//            //collect的key是建筑物结构类型+设防雷度+破坏程度   value是建筑物结构类型+设防雷度+破坏程度下的6~10地震烈度的易损性的数值
//            Map<String, List<YSX>> collect = ysxList.stream().collect(Collectors.groupingBy(ysx->{
//                return ysx.getStructure_type()+"_"+ysx.getFortify()+"_"+ysx.getDamage_degree();
//            }));
//
//            collect.forEach((k, v) -> {
//                YSX ysx = v.get(0);
//                List<BigDecimal> intensitySyxValueList = new ArrayList<>(10);
//                intensitySyxValueList.add(BigDecimal.valueOf(ysx.getIntensity6()).divide(BigDecimal.valueOf(100),6, RoundingMode.HALF_DOWN));
//                intensitySyxValueList.add(BigDecimal.valueOf(ysx.getIntensity7()).divide(BigDecimal.valueOf(100),6,RoundingMode.HALF_DOWN));
//                intensitySyxValueList.add(BigDecimal.valueOf(ysx.getIntensity8()).divide(BigDecimal.valueOf(100),6,RoundingMode.HALF_DOWN));
//                intensitySyxValueList.add(BigDecimal.valueOf(ysx.getIntensity9()).divide(BigDecimal.valueOf(100),6,RoundingMode.HALF_DOWN));
//                intensitySyxValueList.add(BigDecimal.valueOf(ysx.getIntensity10()).divide(BigDecimal.valueOf(100),6,RoundingMode.HALF_DOWN));
//                map.put(k,intensitySyxValueList);
//            });
//        }
//        return map;
//    }
    public Map<String, List<BigDecimal>> getYsxMap(String province, String city, String county,Map<String,Map<String, List<BigDecimal>>> disrictYsxMap) throws BizException {
        Map<String, List<BigDecimal>> map = new HashMap<>();
        //查询县的易损性数据
        if(!disrictYsxMap.containsKey(province+"-"+city+"-"+county)){
            List<YSXEntity> ysxEntityList =  ysxRepository.getYSX(province, city, county);
            if (ysxEntityList == null || ysxEntityList.size() == 0) {
                throw new RuntimeException("评估失败,请维护" + province + "-" + city + "-" + county + "的易损性数据");
            }
            if (PlatformObjectUtils.isNotEmpty(ysxEntityList)) {
                //collect的key是建筑物结构类型+设防雷度+破坏程度   value是建筑物结构类型+设防雷度+破坏程度下的6~10地震烈度的易损性的数值
                Map<String, List<YSXEntity>> collect = ysxEntityList.stream().collect(Collectors.groupingBy(ysx->{
                    return ysx.getStructure_type()+"_"+ysx.getFortify()+"_"+ysx.getDamage_degree();
                }));
                collect.forEach((k, v) -> {
                    YSXEntity ysxEntity = v.get(0);
                    List<BigDecimal> intensitySyxValueList = new ArrayList<>(10);
                    intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity6()).divide(BigDecimal.valueOf(100),6, RoundingMode.HALF_DOWN));
                    intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity7()).divide(BigDecimal.valueOf(100),6,RoundingMode.HALF_DOWN));
                    intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity8()).divide(BigDecimal.valueOf(100),6,RoundingMode.HALF_DOWN));
                    intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity9()).divide(BigDecimal.valueOf(100),6,RoundingMode.HALF_DOWN));
                    intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity10()).divide(BigDecimal.valueOf(100),6,RoundingMode.HALF_DOWN));
                    map.put(k,intensitySyxValueList);
                });
                disrictYsxMap.put(province+"-"+city+"-"+county,map);
                return map;
            }
        }
        return disrictYsxMap.get(province+"-"+city+"-"+county);

    }

    /**
     * 查fai表
     *
     */
    private static BigDecimal getFai(BigDecimal value) {
        // 创建一个标准正态分布对象
        NormalDistribution normalDistribution = new NormalDistribution(0, 1);
        // 使用 inverseCumulativeProbability 方法获取对应的 x 值
        double result = normalDistribution.inverseCumulativeProbability(value.doubleValue());
        return BigDecimal.valueOf(result);
    }

    public static HashMap<String, BigDecimal> getMrdAndBrm(List<BigDecimal> xValues, List<BigDecimal> yValues) {
        ArrayList<BigDecimal> faiList = new ArrayList<>();
        ArrayList<BigDecimal> logList = new ArrayList<>();
        ArrayList<BigDecimal> x2 = new ArrayList<>();

        //x的值
        for (BigDecimal xValue : xValues) {
            BigDecimal fai = BigDecimal.ZERO;
            if (xValue.compareTo(BigDecimal.ZERO) == 0) {
                fai = BigDecimal.valueOf(-3.9);
            } else if (xValue.compareTo(BigDecimal.valueOf(1)) == 0) {
                fai = BigDecimal.valueOf(-4.9);
            } else {
                fai = getFai(xValue);
            }
            faiList.add(fai);
        }

        //y的值
        for (BigDecimal yValue : yValues) {
            double log = Math.log(yValue.doubleValue());
            logList.add(BigDecimal.valueOf(log));
        }

        //求x的平均值
        BigDecimal xAverageValue = faiList.stream()
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(BigDecimal.valueOf(faiList.size()), 2, RoundingMode.HALF_UP);

        //求y的平均值
        BigDecimal yAverageValue = logList.stream()
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(BigDecimal.valueOf(faiList.size()), 2, RoundingMode.HALF_UP);


        ArrayList<BigDecimal> newXList = new ArrayList<>();
        faiList.forEach(fai -> {
            BigDecimal subtract = fai.subtract(xAverageValue);
            x2.add(subtract.pow(2));
            newXList.add(subtract);
        });

        ArrayList<BigDecimal> newYList = new ArrayList<>();
        logList.forEach(log -> {
            BigDecimal subtract = log.subtract(yAverageValue);
            newYList.add(subtract);
        });

        //相乘
        ArrayList<BigDecimal> bigDecimals = new ArrayList<>();
        if (newXList.size() == newYList.size()) {
            for (int i = 0; i < newYList.size(); i++) {
                BigDecimal multipliedValue = newYList.get(i).multiply(newXList.get(i));
                bigDecimals.add(multipliedValue);
            }
        }

        //求和
        BigDecimal sum = bigDecimals.stream()
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal sum1 = x2.stream()
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        //b1
        BigDecimal bRd = null;
        try {
            bRd = sum.divide(sum1, 4, RoundingMode.HALF_UP);
        } catch (Exception e) {
            bRd = BigDecimal.ZERO;
        }
        //b0
        BigDecimal b0 = yAverageValue.subtract(bRd.multiply(xAverageValue));
        double mRd = Math.exp(b0.doubleValue());
        HashMap<String, BigDecimal> map = new HashMap<>();
        map.put("mrd", BigDecimal.valueOf(mRd));
//        log.info("mrd的值:{}",BigDecimal.valueOf(mRd));
        map.put("brd", bRd);
//        log.info("brd的值:{}",bRd);
        return map;
    }

    /**
     * 去除百分号
     *
     */
    public static BigDecimal removalPercentage(String reate) {
        String result = reate.replace("%", "");
        return new BigDecimal(result).divide(BigDecimal.valueOf(100), 6, RoundingMode.UP);
    }
    public static List<CurveVo> turningCurve1(List<YSXMainTable> dataList) {
        ArrayList<CurveVo> resultList = new ArrayList<>();
        Map<String, List<YSXMainTable>> collect = dataList.stream().collect(Collectors.groupingBy(YSXMainTable::getIntensity));
        collect.forEach((k,v)->{
            Map<String, List<YSXMainTable>> damageMap = v.stream().collect(Collectors.groupingBy(YSXMainTable::getDamage));
            List<YSXMainTable> damageList = damageMap.get("倒塌");
            CurveVo cVo = new CurveVo();
            cVo.setIm(transIntensity(damageList.get(0).getIntensity()));
            cVo.setBreakState("倒塌");
            cVo.setFim(removalPercentage(damageList.get(0).getRate()));
            cVo.setSort(4);
            resultList.add(cVo);
            CurveVo edVo = new CurveVo();
            List<YSXMainTable> sList = damageMap.get("严重破坏");
            edVo.setBreakState("严重破坏");
            edVo.setIm(transIntensity(sList.get(0).getIntensity()));
            BigDecimal fim = removalPercentage(damageMap.get("倒塌").get(0).getRate()).add(removalPercentage(sList.get(0).getRate()));
            edVo.setFim(fim);
            edVo.setSort(3);
            resultList.add(edVo);
            CurveVo mdVo = new CurveVo();
            List<YSXMainTable> mList = damageMap.get("中等破坏");
            mdVo.setBreakState("中等破坏");
            mdVo.setIm(transIntensity(mList.get(0).getIntensity()));
            BigDecimal mdFim = removalPercentage(damageMap.get("倒塌").get(0).getRate()).add(removalPercentage(damageMap.get("严重破坏").get(0).getRate())).add(removalPercentage(mList.get(0).getRate()));
            mdVo.setFim(mdFim);
            mdVo.setSort(2);
            resultList.add(mdVo);
            CurveVo sdVo = new CurveVo();
            List<YSXMainTable> lList = damageMap.get("轻微破坏");
            sdVo.setBreakState("轻微破坏");
            sdVo.setIm(transIntensity(lList.get(0).getIntensity()));
            BigDecimal sdFim = removalPercentage(damageMap.get("倒塌").get(0).getRate()).add(removalPercentage(damageMap.get("严重破坏").get(0).getRate())).add(removalPercentage(damageMap.get("中等破坏").get(0).getRate())).add(removalPercentage(lList.get(0).getRate()));
            sdVo.setFim(sdFim);
            sdVo.setSort(1);
            resultList.add(sdVo);
        });
        return resultList;
    }
    public static BigDecimal transIntensity(String intensity){
        BigDecimal param = null;
        switch (intensity) {
            case "5度":
                param = BigDecimal.valueOf(0.01);
                break;
            case "6度":
                param = BigDecimal.valueOf(0.05);
                break;
            case "7度":
                param = BigDecimal.valueOf(0.1);
                break;
            case "8度":
                param = BigDecimal.valueOf(0.2);
                break;
            case "9度":
                param =  BigDecimal.valueOf(0.4);
                break;
            case "10度":
                param =  BigDecimal.valueOf(0.8);
                break;
        }
        return param;
    }
    /**
     * 矩阵转曲线
     */
    public static List<BasicLibraryVo.stateValue> turningCurve(List<YSXMainTable> matrix) {
        List<BigDecimal> xList = new ArrayList<>();
        ArrayList<BigDecimal> yList = new ArrayList<>();
        ArrayList<BasicLibraryVo.stateValue> stateValueList = new ArrayList<>();
        Map<String, List<YSXMainTable>> damageMap = matrix.stream().collect(Collectors.groupingBy(YSXMainTable::getDamage));
        damageMap.forEach((k,v)->{
            BasicLibraryVo.stateValue entity = new BasicLibraryVo.stateValue();
            //v是不同烈度相同破坏程度的集合
            for (YSXMainTable it : v) {
                xList.add(removalPercentage(it.getRate()));
                switch (it.getIntensity()) {
                    case "5度":
                        yList.add(BigDecimal.valueOf(0.01));
                        break;
                    case "6度":
                        yList.add(BigDecimal.valueOf(0.05));
                        break;
                    case "7度":
                        yList.add(BigDecimal.valueOf(0.1));
                        break;
                    case "8度":
                        yList.add(BigDecimal.valueOf(0.2));
                        break;
                    case "9度":
                        yList.add(BigDecimal.valueOf(0.4));
                        break;
                    case "10度":
                        yList.add(BigDecimal.valueOf(0.8));
                        break;
                }
            }
            HashMap<String, BigDecimal> mrdAndBrm = getMrdAndBrm(xList, yList);
            entity.setDestructiveState(k);
            if("轻微破坏".equals(k)){
                entity.setSort(1);
            }else if("中等破坏".equals(k)){
                entity.setSort(2);
            }else if("严重破坏".equals(k)){
                entity.setSort(3);
            }else if("倒塌".equals(k)){
                entity.setSort(4);
            }
            entity.setMr(mrdAndBrm.get("mrd"));
            entity.setBr(mrdAndBrm.get("brd"));
            stateValueList.add(entity);
        });
        return stateValueList;
    }
    //根据省市县查询出房屋结构,根据房屋结构归并,并且在同一类房屋结构下归并相同的破坏状态
    // return 结构类型,设防状态,破坏程度,list<StateValue>;
    public  void getCenterValue1(String province,String city,String county,String ysxVersion,String taskId,Map<String, Map<String, Table<String, BigDecimal,CurveVo>>> map4) throws Exception {
        List<BasicLibraryVo> list  = null;
        //list是根据省市县查询出来的易损性曲线数据
        if("0".equals(ysxVersion)){
            //0表示国家级数据需要查询承载体的易损性数据
            if(!disrictMap.containsKey(province+"-"+city+"-"+county)){
                JSONArray pgaOfYsx = jcsjRestManager.getPgaOfYsx(province, city, county);
                list = JSONObject.parseArray(JSONObject.toJSONString(pgaOfYsx),BasicLibraryVo.class);
                disrictMap.put(province+"-"+city+"-"+county,list);
            }else{
                list = disrictMap.get(province+"-"+city+"-"+county);
            }
        }else if("2".equals(ysxVersion)){
            //自定义群体版需要查询本系统的易损性数据
            list = new ArrayList<>();
            if(!disrictMap.containsKey(province+"-"+city+"-"+county)){
                List<YSXMainTable> ysx = ysxRepository.getYSX2(taskId, province, city, county);
                Map<String, List<YSXMainTable>> ysxMap = ysx.stream().collect(Collectors.groupingBy(YSXMainTable::getId));
                List<BasicLibraryVo> finalList = list;
                ysxMap.forEach((k, v)->{
                    //k是主表id，v是这个易损性下的多个值
                    BasicLibraryVo vo = new BasicLibraryVo();
                    vo.setStructureType(v.get(0).getStructureType1());
                    if (PlatformObjectUtils.isNotEmpty(v.get(0).getStructureType2())) {
                        vo.setStructureType1(v.get(0).getStructureType2());
                    }
                    vo.setDefenseSituation(v.get(0).getFortify());
                    List<CurveVo> valueList = turningCurve1(v);
                    vo.setValueList(valueList);
                    finalList.add(vo);
                });
                disrictMap.put(province+"-"+city+"-"+county,finalList);
                list = finalList;
            }else{
                list = disrictMap.get(province+"-"+city+"-"+county);
            }
        }
        Map<String, List<BasicLibraryVo>> mapVXX = new HashMap<>();
        for (BasicLibraryVo obj : list) {
            StringBuilder extends1 = new StringBuilder(obj.getStructureType());
            if (null!=obj.getStructureType1()) {
                extends1.append("-").append(obj.getStructureType1());
            }
            List<BasicLibraryVo> newList;
            if (mapVXX.containsKey(extends1.toString())) {
                newList = mapVXX.get(extends1.toString());
            } else {
                newList = new ArrayList<>();
            }
            newList.add(obj);
            mapVXX.put(extends1.toString(), newList);
        }
        //结构类型,设防状态,破坏程度,list<StateValue>;
        //Map<String,Map<String, Map<String, CurveVo>>> map4 = new HashMap<>();
        for (Map.Entry<String, List<BasicLibraryVo>> entry : mapVXX.entrySet()) {
            //将设防烈度分开
            Map<String, Table<String, BigDecimal,CurveVo>> map3 = new HashMap<>();
            for (BasicLibraryVo basicLibraryVo : entry.getValue()) {
                String defState = basicLibraryVo.getDefenseSituation();
                //将破坏状态分开
                //key为破坏状态
                Table<String, BigDecimal,CurveVo> map2 = HashBasedTable.create();
                for (CurveVo stateValue : basicLibraryVo.getValueList()) {
                    String state = stateValue.getBreakState();
                    BigDecimal im = stateValue.getIm();
                    map2.put(state,im, stateValue);
                }
                //设防烈度.破坏状态
                map3.put(defState,map2);
            }
            map4.put(entry.getKey(),map3);
        }
    }


    /**
     * 概率评估-发生概率地震危险性的pga时的计算
     *
     * @param mapKey      易损性承灾体的结构类型
     * @param sfIntensity 设防情况
     * @param jsonObject 承灾体易损性的易损性曲线数据-结构类型，设防情况，破坏状态，函数
     * @param mapMap1     pga查询对应的发生概率地震危险性数据
     */
    public Map<String, Map<String, Map<String, BigDecimal>>>  centerEvaluate1(String mapKey, String sfIntensity,JSONObject jsonObject,
                                Map<String, Map<List<String>, List<BigDecimal>>> mapMap1) {
        /**
         * key:格网id
         * value:Map<String,Map<String, BigDecimal>>
         */
        Map<String, Map<String, Map<String, BigDecimal>>> mapMapMap = new HashMap<>();
        /**
         * key:破坏程度
         * value:Map<String,BigDecimal>
         */
        Map<String, Map<String, BigDecimal>> mapMap = null;
        /**
         * key:结构类型
         * value:
         */
        Map<String, BigDecimal> map = null;

        for (Map.Entry<String, Map<List<String>, List<BigDecimal>>> entries1 : mapMap1.entrySet()) {
            String gridId = entries1.getKey();
            //一个公里网格下的危险性数据，年平均发生概率，key为X轴IM(g)，value为Y轴年平均发生概率
            Map<List<String>, List<BigDecimal>> listMap1 = entries1.getValue();
            if (mapMapMap.containsKey(gridId)) {
                mapMap = mapMapMap.get(gridId);
            } else {
                mapMap = new HashMap<>();
            }
            for (Map.Entry<List<String>, List<BigDecimal>> entries2 : listMap1.entrySet()) {
                List<String> key = entries2.getKey();//IM(g)
                List<BigDecimal> value = entries2.getValue();//年平均发生概率
                for (int i = 0; i < key.size(); i++) {
                    String im = key.get(i);//单个IM(g)值
                    BigDecimal yIm = value.get(i);//单个年平均发生概率的值
                    JSONArray jsonArray1 = null;
                    // for (int j=0;j<jsonArray.size();j++){
                    //结构类型，设防情况，破坏状态，函数
                    jsonArray1 = jsonObject.getJSONArray("valueList");
                    //destructiveState1破坏程度的通过易损性曲线函数得到im对应的易损性值fai1
                    JSONObject jsonObject1 = jsonArray1.getJSONObject(0);
                    BigDecimal fai1 = getFuntionValue(jsonObject1,im);

                    JSONObject jsonObject2 = jsonArray1.getJSONObject(1);
                    BigDecimal fai2 = getFuntionValue(jsonObject2,im);

                    JSONObject jsonObject3 = jsonArray1.getJSONObject(2);
                    BigDecimal fai3 = getFuntionValue(jsonObject3,im);

                    JSONObject jsonObject4 = jsonArray1.getJSONObject(3);
                    BigDecimal fai4 = getFuntionValue(jsonObject4,im);

                    if (mapMap.containsKey("轻微破坏")) {
                        map = mapMap.get("轻微破坏");
                    } else {
                        map = new HashMap<>();
                    }
                    BigDecimal bigDecimal1 = map.getOrDefault(mapKey, BigDecimal.ZERO);
                    //轻微破坏
                    BigDecimal P1 = yIm.multiply(fai2.subtract(fai1));
                    map.put(mapKey, bigDecimal1.add(P1));
                    mapMap.put("轻微破坏", map);

                    if (mapMap.containsKey("中等破坏")) {
                        map = mapMap.get("中等破坏");
                    } else {
                        map = new HashMap<>();
                    }
                    BigDecimal bigDecimal2 = map.getOrDefault(mapKey, BigDecimal.ZERO);
                    //中等破坏
                    BigDecimal P2 = yIm.multiply(fai3.subtract(fai2));
                    map.put(mapKey, bigDecimal2.add(P2));
                    mapMap.put("中等破坏", map);

                    if (mapMap.containsKey("严重破坏")) {
                        map = mapMap.get("严重破坏");
                    } else {
                        map = new HashMap<>();
                    }
                    BigDecimal bigDecimal3 = map.getOrDefault(mapKey, BigDecimal.ZERO);
                    //严重破坏
                    BigDecimal P3 = yIm.multiply(fai4.subtract(fai3));
                    map.put(mapKey, bigDecimal3.add(P3));
                    mapMap.put("严重破坏", map);

                    if (mapMap.containsKey("倒塌")) {
                        map = mapMap.get("倒塌");
                    } else {
                        map = new HashMap<>();
                    }
                    BigDecimal bigDecimal4 = map.getOrDefault(mapKey, BigDecimal.ZERO);
                    //倒塌
                    BigDecimal P4 = yIm.multiply(fai4);
                    map.put(mapKey, bigDecimal4.add(P4));
                    mapMap.put("倒塌", map);
                    // }
                }
            }
            mapMapMap.put(gridId, mapMap);
        }
        return mapMapMap;
    }

    /**
     * 计算fai
     *
     * @param u
     */
    private static BigDecimal selfCaculate(BigDecimal u) {
        BigDecimal ret = BigDecimal.valueOf(0);
        if (u.compareTo(BigDecimal.valueOf(-3.89)) < 0) {
            return new BigDecimal(0);
        } else if (u.compareTo(BigDecimal.valueOf(3.89)) > 0) {
            return new BigDecimal(1);
        }
        BigDecimal temp = BigDecimal.valueOf(-3.89);
        while (temp.compareTo(u) < 1) {
            ret = ret.add(BigDecimal.valueOf(0.0001).multiply(fx(temp)));
            temp = temp.add(BigDecimal.valueOf(0.0001));
        }
        return ret;
    }

    private static BigDecimal fx(BigDecimal x) {
        double a = 1.0 / Math.sqrt(Math.PI * 2);
        a = a * Math.pow(Math.E, -0.5 * Math.pow(Double.parseDouble(x.toString()), 2));
        return BigDecimal.valueOf(a);
    }

    /**
     * 根据空间数据和版本查询房屋单体数据
     */
    public List<BuildingIndividualEntity> getBuildingIndividualVOs(String geom, String version) throws StrategyFactoryException {
        List<BuildingIndividualEntity> list = new ArrayList<>();
        QueryByVersionParam queryByVersionParam = new QueryByVersionParam();
        queryByVersionParam.setVersionCode(version);
        queryByVersionParam.setGeom(geom);
        queryByVersionParam.setGeomType(1);
        list = buildingIndividualRepository.queryYwData(queryByVersionParam);

        return list;
    }

    // List<BigDecimal> decimals=Arrays.asList(BigDecimal.valueOf(0.01968864),BigDecimal.valueOf(0.00210499),BigDecimal.valueOf(0.00040397),BigDecimal.valueOf(0.0001005));
    List<BigDecimal> decimals=Arrays.asList(BigDecimal.valueOf(0.01762074),BigDecimal.valueOf(0.00170171),
            BigDecimal.valueOf(0.0003035),BigDecimal.valueOf(-0.00040396));
    /**
     * 超越概率转发生概率
     * 烈度
     * 组建数据   格式为<空间数据,0.01,0.999969>
     *     公式P1=1-Math.pow((1-PT),1/T)
     *     50年63%:0.01968864;50年10%:0.00210499;50年2%:0.00040397;100年1%:0.0001005
     * @Param type 0:网格;1:单体;
     *
     * @return
     */
    public Table<String,List<String>,List<BigDecimal>> transition1(String geom, String version, String type) throws BizException {
        Table<String,List<String>,List<BigDecimal>> table= HashBasedTable.create();
        JcLDBo ldList1 = jcsjRestManager.getLDList1(geom, version);
        if (ldList1!=null){
            List<JcLd> data = ldList1.getData();
            Map<String, List<JcLd>> collect = null;
            if ("0".equals(type)){
                collect = data.stream().collect(Collectors.groupingBy(JcLd::getExtends1));
            }else {
                collect = data.stream().collect(Collectors.groupingBy(JcLd::getGeom));
            }
            collect.forEach((k, v) -> {
                List<String> valus = new ArrayList<>();
                List<BigDecimal> fvalus = new ArrayList<>();
                v.forEach(entity -> {
                    init(entity.getLd50year63(),valus);
                    init(entity.getLd50year10(),valus);
                    init(entity.getLd50year2(),valus);
                    init(entity.getLd100year1(),valus);

                    fvalus.addAll(decimals);
                });
                table.put(k, valus, fvalus);
            });
            if (table.size() > 0) {
                return table;
            }
            return null;

        }
        return null;
    }

    /**
     * 要跟发生地震危险性的烈度保持一致
     * @param ld
     * @param valus
     */
    private void init(String ld, List<String> valus){
        switch (ld){
            case "≤5":valus.add("Ⅴ");break;
            case "6":valus.add("Ⅵ");break;
            case "7":valus.add("Ⅶ");break;
            case "8":valus.add("Ⅷ");break;
            case "9":valus.add("Ⅸ");break;
            case "10":valus.add("Ⅹ");break;
            case "11":valus.add("Ⅺ");break;
            case "12":valus.add("Ⅻ");break;
        }
    }

    /**
     * pga
     * @Param type 0:网格;1:单体;
     */
    public Table<String,List<String>,List<BigDecimal>> transition2(String geom, String version, String type) throws BizException {
        Table<String,List<String>,List<BigDecimal>> table= HashBasedTable.create();
        JcPgaBo pagList1 = jcsjRestManager.getPagList1(geom, version);
        if (pagList1!=null){
            List<JcPga> data = pagList1.getData();
            Map<String, List<JcPga>> collect = null;
            if ("0".equals(type)){
                collect = data.stream().collect(Collectors.groupingBy(JcPga::getExtends1));
            }else {
                collect = data.stream().collect(Collectors.groupingBy(JcPga::getGeom));
            }
            collect.forEach((k, v) -> {
                List<String> valus = new ArrayList<>();
                List<BigDecimal> fvalus = new ArrayList<>();
                v.forEach(entity -> {
                    valus.add(entity.getPga50year63()+"");
                    valus.add(entity.getPga50year10()+"");
                    valus.add(entity.getPga50year2()+"");
                    valus.add(entity.getPga100year1()+"");

                    fvalus.addAll(decimals);
                });
                table.put(k, valus, fvalus);
            });
            if (table.size() > 0) {
                return table;
            }
            return null;

        }
        return null;
    }


    public List<BuildingIndividualVulnerability> getBuildingIndividualVulnerabilityList(BuildingIndividualEntity obj) {
        return publicOperateRepository.getBuildingIndividualVulnerabilityList(obj.getLongitude().toString(), obj.getLatitude().toString());
    }
}
